home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / xlib / xlib06 / xpolygon.asm < prev    next >
Assembly Source File  |  1993-09-12  |  15KB  |  608 lines

  1. ;-----------------------------------------------------------------------
  2. ; MODULE XPOLYGON
  3. ;
  4. ; Filled Triangle function for all MODE X 256 Color resolutions
  5. ;
  6. ; Compile with Tasm.
  7. ; C callable.
  8. ;
  9. ; ****** XLIB - Mode X graphics library                ****************
  10. ; ******                                               ****************
  11. ; ****** Written By Themie Gouthas                     ****************
  12. ;
  13. ; This module is based on code developed by Steve Dollind for his
  14. ; XSPACE game.
  15. ; Copyright (C) 1992 Steven Dollins  --  sdollins@uiuc.edu
  16. ;
  17. ;
  18. ; egg@dstos3.dsto.gov.au
  19. ; teg@bart.dsto.gov.au
  20. ;-----------------------------------------------------------------------
  21. include xlib.inc
  22. include xpolygon.inc
  23.  
  24. .data
  25. ; Plane masks for clipping left and right edges of rectangle.
  26.     LeftClipPlaneMask       db      00fh,00eh,00ch,008h
  27.     RightClipPlaneMask      db      00fh,001h,003h,007h
  28.  
  29. .code
  30.  
  31.  
  32. ;-----------------------------------------------------------------------
  33. ; void HLineClipR
  34. ;
  35. ;       Draws a horizontal line from (X1, Y) to (X2, Y).
  36. ;       Uses Watcom Parameter passing convention in registers
  37. ;
  38. ;   X1 in AX
  39. ;   X2 in DX
  40. ;   Y in CX
  41. ;   Color in BX
  42. ;   PageOffset in DI
  43. ;
  44. ; By Themie Gouthas - Adapted from x_fill_rect.
  45. ;-----------------------------------------------------------------------
  46. proc _HLineClipR near
  47.     push    di
  48.     cmp     dx,ax                ; if (X2 < X1) then assume no line
  49.     jl      @@Invisible          ;   is visible
  50.  
  51.     cmp     cx,[_TopClip]        ; if (Y < TopClip) then no line
  52.     jl      @@Invisible
  53.  
  54.     cmp     cx,[_BottomClip]     ;if (Y > BottomClip) then no line
  55.     jg      @@Invisible
  56.  
  57.     mov     di,[_RightClip]      ;convert RightClip to pixel coords
  58.     sal     di,2
  59.     cmp     ax,di                ; if (X1 > RightClip) then no line
  60.     jg      @@Invisible
  61.  
  62.     cmp     dx,di                ; if (X2 > RightClip) then
  63.     jle     @@ClipLeft           ;  X2:=RightClip
  64.     mov     dx,di
  65.  
  66. @@ClipLeft:
  67.     mov     di,[_LeftClip]       ;convert LeftClip to pixel coords
  68.     sal     di,2
  69.         cmp     dx,di                ; if (X2 < LeftClip) then no line
  70.         jl      @@Invisible
  71.  
  72.     cmp     ax,di                ;if (X1 > LeftClip) then were ready to plot
  73.     jge     @@DoLine
  74.  
  75.     mov     ax,di                ;  X1:=LeftClip
  76.         jmp     short @@DoLine
  77.  
  78. @@Invisible:
  79.     pop     di
  80.     ret
  81.  
  82. @@DoLine:
  83.         pop     di                      ; di = PageOffset
  84.     xchg    cx,ax                   ; AX = Y,  CX = X1
  85.         mov     si,dx                   ; SI = DX = X2
  86.     mul     [_ScrnLogicalByteWidth]
  87.         mov     dx,si                   ; Reset DX to X1 since mul erases DX
  88.     add     ax,di
  89.     mov     di,cx
  90.     sar     di,2                    ; Convert to bytes
  91.     add     di,ax                   ; DI->First byte
  92.  
  93.         and     si,03h                  ; look up right edge plane mask
  94.     mov     ah,RightClipPlaneMask[si]
  95.     mov     si,cx                   ; look up left edge plane mask
  96.     and     si,03h
  97.     mov     al,LeftClipPlaneMask[si]
  98.  
  99.     cmp     dx,cx                   ; No harm in being paranoid..
  100.     jle     @@Invisible2
  101.  
  102.     xchg    cx,dx                   ;CX=X2, DX=X1
  103.     dec     cx
  104.     and     dx,not 03h
  105.     sub     cx,dx
  106.         js      @@Invisible2
  107.     shr     cx,2
  108.     jnz     @@MasksSet
  109.     and     al,ah
  110. @@MasksSet:
  111.     mov     dl,bl                 ; set BX=Plane Masks, AH=Color
  112.     mov     bx,ax
  113.     mov     ah,dl
  114.     mov     dx,SC_INDEX+1         ;set the Sequence Controller Index to
  115.     mov     al,bl
  116.     out     dx,al
  117.         mov     al,ah
  118.     stosb                         ; Plot left byte
  119.     dec     cx
  120.     js      @@Invisible2
  121.     jz      @@RightEnd
  122.  
  123.  
  124.     mov     al,0fh                ; plot middle bytes
  125.     out     dx,al
  126.         mov     al,ah
  127.         shr     cx,1
  128.     rep     stosw
  129.         adc     cx,cx
  130.         rep     stosb
  131.  
  132.  
  133.  
  134. @@RightEnd:
  135.     mov     al,bh              ; Plot right  byte
  136.     out     dx,al
  137.         mov     al,ah
  138.     stosb
  139. @@Invisible2:
  140.     ret
  141. _HLineClipR endp
  142.  
  143.  
  144. ;-----------------------------------------------------------------------
  145. ; void x_triangle( int X0, int Y0, int X1, int Y1,
  146. ;                int X2, int Y2, unsigned Color, unsigned PageOffset );
  147. ;
  148. ;
  149. ; Written by S. Dollins
  150.  
  151. _x_triangle  proc
  152. ARG   X0:word,Y0:word,X1:word,Y1:word,X2:word,Y2:word,Color:word,PageOffset:word
  153. LOCAL DX01:word, DY01:word, DX02:word, DY02:word, DX12:word, DY12:word, \
  154.       DP01:word, DP02:word, DP12:word, XA01:word, XA02:word, XA12:word=STK
  155.  
  156.     push    bp
  157.     mov     bp,sp
  158.     sub     sp,STK
  159.     push    ds es si di  ; Save es for polygon routine
  160.  
  161.     mov     ax,X0
  162.     mov     bx,Y0
  163.     mov     cx,X1
  164.     mov     dx,Y1
  165.  
  166.     cmp     bx,dx   ; Y0,Y1
  167.     jl      tri_Y0lY1
  168.     je      tri_Y0eY1
  169.     xchg    ax,cx   ; X0,X1
  170.     xchg    bx,dx   ; Y0,Y1
  171. tri_Y0lY1:
  172.     cmp     dx,Y2   ; Y1,Y2
  173.     jg      tri_a
  174.     jmp     tri_sorted
  175. tri_a:  xchg    cx,X2   ; X1,X2
  176.     xchg    dx,Y2   ; Y1,Y2
  177.     cmp     bx,dx   ; Y0,Y1
  178.     jge     tri_b
  179.     jmp     tri_sorted
  180. tri_b:  je      tri_bot
  181.     xchg    ax,cx   ; X0,X1
  182.     xchg    bx,dx   ; Y0,Y1
  183.     jmp     tri_sorted
  184. tri_Y0eY1:
  185.     cmp     bx,Y2   ; Y0,Y2
  186.     jl      tri_bot
  187.     jg      tri_c
  188.     jmp     tri_done
  189. tri_c:  xchg    ax,X2   ; X0,X2
  190.     xchg    bx,Y2   ; Y0,Y2
  191.     jmp     tri_sorted
  192.  
  193. tri_bot:
  194.     cmp     ax,cx   ; X0,X1
  195.     jl      tri_bot_sorted
  196.     jg      tri_bot_a
  197.     jmp     tri_done
  198. tri_bot_a:
  199.     xchg    ax,cx   ; X0,X1
  200. tri_bot_sorted:
  201.     cmp     bx,[_BottomClip]
  202.     jle     tri_bot_y0ok
  203.     jmp     tri_done
  204. tri_bot_y0ok:
  205.     mov     si,Y2
  206.     cmp     si,[_TopClip]
  207.     jge     tri_bot_y2ok
  208.     jmp     tri_done
  209. tri_bot_y2ok:
  210.     mov     X0,ax
  211.     mov     Y0,bx
  212.     mov     X1,cx
  213.     mov     Y1,dx
  214.  
  215.     mov     bx,Y2   ;    bx <- Y2
  216.     sub     bx,Y0   ;    bx <- Y2 - Y0
  217.     mov     DY02,bx ;  DY02 <- Y2 - Y0
  218.     mov     ax,X2   ;    ax <- X2
  219.     sub     ax,X0   ;    ax <- X2 - X0
  220.     mov     DX02,ax ;  DX02 <- X2 - X0
  221.     mov     cx,ax   ;    cx <- DX02
  222.     cwd             ; dx:ax <- DX02
  223.     idiv    bx      ;    ax <- DX02 / DY02
  224.     cmp     cx,0
  225.     jge     short tri_bot02
  226.     dec     ax      ;    ax <- DX02 / DY02 - 1
  227. tri_bot02:
  228.     mov     XA02,ax ;  XA02 <- DX02 / DY02
  229.     imul    bx      ;    ax <- XA02 * DY02
  230.     sub     cx,ax   ;    cx <- DX02 - XA02 * DY02
  231.     mov     DP02,cx ;  DP02 <- DX02 - XA02 * DY02
  232.  
  233.     mov     bx,Y2   ;    bx <- Y2
  234.     sub     bx,Y1   ;    bx <- Y2 - Y1
  235.     mov     DY12,bx ;  DY02 <- Y2 - Y1
  236.     mov     ax,X2   ;    ax <- X2
  237.     sub     ax,X1   ;    ax <- X2 - X1
  238.     mov     DX12,ax ;  DX12 <- X2 - X1
  239.     mov     cx,ax   ;    cx <- DX12
  240.     cwd             ; dx:ax <- DX12
  241.     idiv    bx      ;    ax <- DX12 / DY12
  242.     cmp     cx,0
  243.     jge     short tri_bot12
  244.     dec     ax      ;    ax <- DX12 / DY12 - 1
  245. tri_bot12:
  246.     mov     XA12,ax ;  XA12 <- DX12 / DY12
  247.     imul    bx      ;    ax <- XA12 * DY12
  248.     sub     cx,ax   ;    cx <- DX12 - XA12 * DY12
  249.     mov     DP12,cx ;  DP12 <- DX12 - XA12 * DY12
  250.  
  251.     mov     ax,0    ; PL <- 0
  252.     mov     bx,0    ; PS <- 0
  253.     mov     cx,Y0   ;  Y <- Y0
  254.     mov     si,X0
  255.     mov     di,X1
  256.     dec     di
  257. tri_bot_loop:
  258.     inc     cx      ; Y
  259.  
  260.     add     ax,DP02 ; PL,DP02
  261.     jle     short tri_bot_shortl
  262.     sub     ax,DY02 ; PL,DY02
  263.     inc     si      ; XL
  264. tri_bot_shortl:
  265.     add     si,XA02 ; XL,XA02
  266.  
  267.     add     bx,DP12 ; PS,DP12
  268.     jle     short tri_bot_shortr
  269.     sub     bx,DY12 ; PS,DY12
  270.     inc     di      ; XS
  271. tri_bot_shortr:
  272.     add     di,XA12 ; XS,XA12
  273.  
  274.     push    di      ; XS
  275.     push    si      ; XL
  276.     cmp     cx,Y2   ; Y,Y2
  277.     jl      short tri_bot_loop
  278.  
  279.     jmp     tri_draw_lines
  280.  
  281.  
  282. tri_sorted:
  283.     cmp     bx,[_BottomClip]
  284.     jle     tri_y0ok
  285.     jmp     tri_done
  286. tri_y0ok:
  287.     mov     si,Y2
  288.     cmp     si,[_TopClip]
  289.     jge     tri_y2ok
  290.     jmp     tri_done
  291. tri_y2ok:
  292.     mov     X0,ax
  293.     mov     Y0,bx
  294.     mov     X1,cx
  295.     mov     Y1,dx
  296.  
  297.     mov     bx,dx   ;    bx <- Y1
  298.     sub     bx,Y0   ;    bx <- Y1 - Y0
  299.     mov     DY01,bx ;  DY01 <- Y1 - Y0
  300.     mov     ax,X1   ;    ax <- X1
  301.     sub     ax,X0   ;    ax <- X1 - X0
  302.     mov     DX01,ax ;  DX01 <- X1 - X0
  303.     mov     cx,ax   ;    cx <- DX01
  304.     cwd             ; dx:ax <- DX01
  305.     idiv    bx      ;    ax <- DX01 / DY01
  306.     cmp     cx,0    ;  DX01 ? 0
  307.     jge     short tri_psl01
  308.     dec     ax      ;    ax <- DX01 / DY01 - 1
  309. tri_psl01:
  310.     mov     XA01,ax ;  XA01 <- DX01 / DY01
  311.     imul    bx      ;    ax <- XA01 * DY01
  312.     sub     cx,ax   ;    cx <- DX01 - XA01 * DY01
  313.     mov     DP01,cx ;  DP01 <- DX01 - XA01 * DY01
  314.  
  315.     mov     bx,Y2   ;    bx <- Y2
  316.     sub     bx,Y0   ;    bx <- Y2 - Y0
  317.     mov     DY02,bx ;  DY02 <- Y2 - Y0
  318.     mov     ax,X2   ;    ax <- X2
  319.     sub     ax,X0   ;    ax <- X2 - X0
  320.     mov     DX02,ax ;  DX02 <- X2 - X0
  321.     mov     cx,ax   ;    cx <- DX02
  322.     cwd             ; dx:ax <- DX02
  323.     idiv    bx      ;    ax <- DX02 / DY02
  324.     cmp     cx,0
  325.     jge     short tri_psl02
  326.     dec     ax      ;    ax <- DX02 / DY02 - 1
  327. tri_psl02:
  328.     mov     XA02,ax ;  XA02 <- DX02 / DY02
  329.     imul    bx      ;    ax <- XA02 * DY02
  330.     sub     cx,ax   ;    cx <- DX02 - XA02 * DY02
  331.     mov     DP02,cx ;  DP02 <- DX02 - XA02 * DY02
  332.  
  333.     mov     bx,Y2   ;    bx <- Y2
  334.     sub     bx,Y1   ;    bx <- Y2 - Y1
  335.     jle     short tri_const_computed
  336.     mov     DY12,bx ;  DY12 <- Y2 - Y1
  337.     mov     ax,X2   ;    ax <- X2
  338.     sub     ax,X1   ;    ax <- X2 - X1
  339.     mov     DX12,ax ;  DX12 <- X2 - X1
  340.     mov     cx,ax   ;    cx <- DX12
  341.     cwd             ; dx:ax <- DX12
  342.     idiv    bx      ;    ax <- DX12 / DY12
  343.     cmp     cx,0
  344.     jge     short tri_psl12
  345.     dec     ax      ;    ax <- DX12 / DY12 - 1
  346. tri_psl12:
  347.     mov     XA12,ax ;  XA12 <- DX12 / DY12
  348.     imul    bx      ;    ax <- XA12 * DY12
  349.     sub     cx,ax   ;    cx <- DX12 - XA12 * DY12
  350.     mov     DP12,cx ;  DP12 <- DX12 - XA12 * DY12
  351.  
  352. tri_const_computed:
  353.     mov     ax,DX01
  354.     imul    word ptr DY02
  355.     mov     bx,ax
  356.     mov     cx,dx   ; DX01 * DY02 in cx:bx
  357.  
  358.     mov     ax,DX02
  359.     imul    word ptr DY01 ; DX02 * DY01 in dx:ax
  360.     cmp     cx,dx
  361.     jg      tri_pt1rt
  362.     jl      tri_pt1lt
  363.     cmp     bx,ax
  364.     ja      tri_pt1rt
  365.     jb      tri_pt1lt
  366.     jmp     tri_done
  367.  
  368. ;------------------------------------
  369. ; Short sides are on the left
  370. ;
  371. tri_pt1lt:
  372.     mov     ax,0    ; PL <- 0
  373.     mov     bx,0    ; PS <- 0
  374.     mov     cx,Y0   ;  Y <- Y0
  375.     mov     si,X0
  376.     mov     di,si
  377.     dec     si
  378. tri_lt_loop:
  379.     inc     cx      ; Y
  380.  
  381.     add     ax,DP02 ; PL,DP02
  382.     jle     short tri_lt_shortl
  383.     sub     ax,DY02 ; PL,DY02
  384.     inc     si      ; XL
  385. tri_lt_shortl:
  386.     add     si,XA02 ; XL,XA02
  387.  
  388.     add     bx,DP01 ; PS,DP01
  389.     jle     short tri_lt_shortr
  390.     sub     bx,DY01 ; PS,DY01
  391.     inc     di      ; XS
  392. tri_lt_shortr:
  393.     add     di,XA01 ; XS,XA01
  394.  
  395.     push    si      ; XL
  396.     push    di      ; XS
  397.     cmp     cx,Y1   ; Y,Y1
  398.     jl      short tri_lt_loop
  399.  
  400.     jmp     short tri_lb_start
  401. tri_lb_loop:
  402.     inc     cx      ; Y
  403.  
  404.     add     ax,DP02 ; PL,DP02
  405.     jle     short tri_lb_shortl
  406.     sub     ax,DY02 ; PL,DY02
  407.     inc     si      ; XL
  408. tri_lb_shortl:
  409.     add     si,XA02 ; XL,XA02
  410.  
  411.     add     bx,DP12 ; PS,DP12
  412.     jle     short tri_lb_shortr
  413.     sub     bx,DY12 ; PS,DY12
  414.     inc     di      ; XS
  415. tri_lb_shortr:
  416.     add     di,XA12 ; XS,XA12
  417.  
  418.     push    si      ; XL
  419.     push    di      ; XS
  420. tri_lb_start:
  421.     cmp     cx,Y2   ; Y,Y2
  422.     jl      tri_lb_loop
  423.     jmp     short tri_draw_lines
  424.  
  425. ;------------------------------------
  426. ; short sides are on the right
  427. ;
  428. tri_pt1rt:
  429.     mov     ax,0    ; PL <- 0
  430.     mov     bx,0    ; PS <- 0
  431.     mov     cx,Y0   ;  Y <- Y0
  432.     mov     si,X0
  433.     mov     di,si
  434.     dec     di
  435. tri_rt_loop:
  436.     inc     cx      ; Y
  437.  
  438.     add     ax,DP02 ; PL,DP02
  439.     jle     short tri_rt_shortl
  440.     sub     ax,DY02 ; PL,DY02
  441.     inc     si      ; XL
  442. tri_rt_shortl:
  443.     add     si,XA02 ; XL,XA02
  444.  
  445.     add     bx,DP01 ; PS,DP01
  446.     jle     short tri_rt_shortr
  447.     sub     bx,DY01 ; PS,DY01
  448.     inc     di      ; XS
  449. tri_rt_shortr:
  450.     add     di,XA01 ; XS,XA01
  451.  
  452.     push    di      ; XS
  453.     push    si      ; XL
  454.     cmp     cx,Y1   ; Y,Y1
  455.     jl      short tri_rt_loop
  456.  
  457.     jmp     short tri_rb_start
  458. tri_rb_loop:
  459.     inc     cx      ; Y
  460.  
  461.     add     ax,DP02 ; PL,DP02
  462.     jle     short tri_rb_shortl
  463.     sub     ax,DY02 ; PL,DY02
  464.     inc     si      ; XL
  465. tri_rb_shortl:
  466.     add     si,XA02 ; XL,XA02
  467.  
  468.     add     bx,DP12 ; PS,DP12
  469.     jle     short tri_rb_shorts
  470.     sub     bx,DY12 ; PS,DY12
  471.     inc     di      ; XS
  472. tri_rb_shorts:
  473.     add     di,XA12 ; XS,XA12
  474.  
  475.     push    di      ; XS
  476.     push    si      ; XL
  477. tri_rb_start:
  478.     cmp     cx,Y2   ; Y,Y2
  479.     jl      short tri_rb_loop
  480.  
  481. ;------------------------------------
  482. ; Draw the horizontal lines
  483. ;
  484.  
  485.  
  486. tri_draw_lines:
  487.  
  488.     mov     cx,SCREEN_SEG       ;point ES to video segment
  489.     mov     es,cx
  490.     mov     dx,SC_INDEX         ;set the Sequence Controller Index to
  491.     mov     al,MAP_MASK         ; point to the Map Mask register
  492.     out     dx,al
  493.  
  494.  
  495. line_loop:
  496.     pop     ax
  497.     pop     dx
  498.     cmp     ax,dx
  499.     jg      tri_draw_next
  500.     mov     bx,Color
  501.     mov     cx,Y2
  502.     add     dx,2
  503.     mov     di,PageOffset
  504.     call    _HLineClipR
  505. tri_draw_next:
  506.     dec     word ptr Y2
  507.     dec     word ptr DY02
  508.     jnz     line_loop
  509.  
  510. tri_done:
  511.     pop     di si es ds
  512.     mov     sp,bp
  513.     pop     bp
  514.     ret
  515. _x_triangle  endp
  516.  
  517. ;-----------------------------------------------------------------------
  518. ; void x_polygon( VERTEX vertices[], int num_vertices,unsigned Color,
  519. ;                unsigned PageOffset );
  520. ;
  521. ; Where VERTEX is defined as:
  522. ;
  523. ; typedef struct {
  524. ;    int X;
  525. ;    int Y;
  526. ; } far VERTEX;
  527. ;
  528. ;
  529. ; Written by T. Gouthas
  530. ;
  531. ;
  532. ;
  533. ; Note: This is just a quick hack of a generalized polygon routine.
  534. ;   The way it works is by splitting up polygons into triangles and
  535. ;   drawing each individual triangle.
  536. ;
  537. ; Obviously this is not as fast as it could be, but for polygons of
  538. ; 4 vertices it should perform quite respectably.
  539. ;
  540. ; Warning: Only works for convex polygons (convex polygons are such
  541. ;  that if you draw a line from any two vertices, every point on that
  542. ;  line will be within the polygon)
  543. ;
  544. ;
  545.  
  546. _x_polygon proc
  547.        ARG   vertices:dword,numvertices:word,Color:word,PageOffset:word
  548.        LOCAL x0:word,y0:word,tri_count:word=STK
  549.        push  bp
  550.        mov   bp,sp
  551.        sub   sp,STK
  552.        push  di si
  553.  
  554.        mov   cx,numvertices
  555.        cmp   cx,3
  556.        jl    @@Done
  557.  
  558.        sub   cx,3
  559.        mov   tri_count,cx      ; Number of triangles to draw
  560.        les   di,vertices       ; ES:DI -> Vertices
  561.  
  562.        mov   ax,es:[di]        ; Save first vertex
  563.        mov   x0,ax
  564.        mov   ax,es:[di+2]
  565.        mov   y0,ax
  566.  
  567.        ; Set up permanent parameter stack frame for
  568.        ; triangle parameters
  569.  
  570.        mov   ax,PageOffset
  571.        push  ax
  572.        mov   ax,Color
  573.        push  ax
  574.  
  575.        sub   sp,12
  576.        mov   si,sp
  577.  
  578. @@NextTriangle:
  579.  
  580.        add   di,4
  581.        mov   ax,es:[di]      ; Vertex 2
  582.        mov   ss:[si],ax
  583.        mov   ax,es:[di+2]
  584.        mov   ss:[si+2],ax
  585.  
  586.        mov   ax,es:[di+4]    ; Vertex 1
  587.        mov   ss:[si+4],ax
  588.        mov   ax,es:[di+6]
  589.        mov   ss:[si+6],ax
  590.  
  591.        mov   ax,x0           ; Vertex 0: The first vertex is
  592.        mov   ss:[si+8],ax    ; part of every triangle
  593.        mov   ax,y0
  594.        mov   ss:[si+10],ax
  595.  
  596.        call  _x_triangle
  597.        dec   tri_count
  598.        jns   @@NextTriangle
  599.  
  600.        add   sp,16    ; Remove triangle stack frame
  601.  
  602. @@Done:
  603.        pop   si di
  604.        mov   sp,bp
  605.        pop   bp
  606.        ret
  607. _x_polygon endp
  608.     end